package com.ywu.application.standard.container.service;

import com.ywu.boot.context.YwuContextHolder;
import com.ywu.boot.exception.YwuRuntimeException;
import com.ywu.common.entity.PageList;
import com.ywu.common.page.PageService;
import com.ywu.common.result.CommonResult;
import com.ywu.common.utils.TimerIdGenerateUtil;
import com.ywu.application.standard.container.data.FrpcManageRepository;
import com.ywu.application.standard.container.dto.FrpcManageDto;
import com.ywu.application.standard.container.entity.FrpcManageEntity;
import com.ywu.application.standard.container.service.frpc.FrpcIniObj;
import com.ywu.application.standard.container.service.frpc.FrpcStatusEntity;
import com.ywu.application.standard.container.service.frpc.ParseFrpcInI;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @ClassName FrpcManageService
 * @Description TODO
 * @Author GroundDemo
 * @Date 2024/7/13 15:42
 * @Version 1.0
 **/
@Service
@Slf4j
public class FrpcManageService {
    @Autowired
    private FrpcManageRepository repository;

    @Autowired
    private ParseFrpcInI parseFrpcInI;

    /**
    * @Author GroundDemo
    * @Description 创建frpc客户端端口映射
    * @Date 16:13 2024/7/13
    * @Param [manageDto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    @Transactional
    public CommonResult<Object> createFrpcInfo(FrpcManageDto manageDto) {
        // 校验入参
        CommonResult<Object> checkRes = checkCreateDto(manageDto);
        if (Objects.nonNull(checkRes)) {
            return checkRes;
        }
        // 构建插入对象
        FrpcManageEntity frpcManageEntity = new FrpcManageEntity();
        BeanUtils.copyProperties(manageDto, frpcManageEntity);
        frpcManageEntity.createInfo(YwuContextHolder.getCurrentContext().getYwuContextUser().getUserAccount());
        // 生成新的随机ID
        frpcManageEntity.setId(TimerIdGenerateUtil.nextId());
        repository.addFrpcManageInfo(frpcManageEntity);
        // 解析远程frpc文件
        Map<String, FrpcIniObj> parseFrpcMap;
        try {
            parseFrpcMap = parseFrpcInI.parseFrpcIni();
        } catch (Exception e) {
            throw new YwuRuntimeException("createFrpcInfo parse Frpc Error !!!");
        }
        if (parseFrpcMap.containsKey(frpcManageEntity.getFrpcName())) {
            throw new YwuRuntimeException("createFrpcInfo Frpc ini has exists frpcName !!!");
        }
        FrpcIniObj frpcIniObj = new FrpcIniObj();
        frpcIniObj.setFrpcName(frpcManageEntity.getFrpcName());
        frpcIniObj.setType(frpcManageEntity.getFrpcType());
        frpcIniObj.setLocal_ip("127.0.0.1");
        frpcIniObj.setLocal_port(frpcManageEntity.getLocalPort());
        frpcIniObj.setRemote_port(frpcManageEntity.getRemotePort());
        parseFrpcMap.put(frpcIniObj.getFrpcName(), frpcIniObj);
        // 重新写入frpc文件
        try {
            parseFrpcInI.reWriteFrpcIni(parseFrpcMap);
        } catch (IOException | IllegalAccessException e) {
            throw new YwuRuntimeException("createFrpcInfo reWriteFrpcIni Error !!!");
        }
        // 调用脚本执行停用和启用frpc
        parseFrpcInI.reloadFrpc();
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 校验入参
    * @Date 16:29 2024/7/13
    * @Param [manageDto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    private CommonResult<Object> checkCreateDto(FrpcManageDto manageDto) {
        // 校验frpcName
        FrpcManageDto searchDto = new FrpcManageDto();
        searchDto.setFrpcName(manageDto.getFrpcName());
        FrpcManageEntity entity = repository.getEntity(searchDto);
        if (Objects.nonNull(entity) && StringUtils.isNoneBlank(entity.getId())) {
            return CommonResult.error().setErrorCode("frpcName has exist!")
                    .setMessage("映射名称已存在");
        }
        // 校验映射本机端口与协议
        searchDto.setFrpcName(null);
        searchDto.setFrpcType(manageDto.getFrpcType());
        searchDto.setLocalPort(manageDto.getLocalPort());
        FrpcManageEntity localPortEntity = repository.getEntity(searchDto);
        if (Objects.nonNull(localPortEntity) && StringUtils.isNoneBlank(localPortEntity.getId())) {
            return CommonResult.error().setErrorCode("localPort with port has exist!")
                    .setMessage("映射本机端口与协议已存在");
        }
        // 校验映射远程端口与协议
        searchDto.setLocalPort(null);
        searchDto.setRemotePort(manageDto.getRemotePort());
        FrpcManageEntity remotePortEntity = repository.getEntity(searchDto);
        if (Objects.nonNull(remotePortEntity) && StringUtils.isNoneBlank(remotePortEntity.getId())) {
            return CommonResult.error().setErrorCode("remotePort with port has exist!")
                    .setMessage("映射远程端口与协议已存在");
        }
        return null;
    }

    /**
    * @Author GroundDemo
    * @Description 删除端口映射
    * @Date 16:38 2024/7/13
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    @Transactional
    public CommonResult<Object> deleteFrpcInfo(FrpcManageDto dto) {
        // 查询数据是否存在
        FrpcManageEntity entity = repository.getEntity(dto);
        if (Objects.isNull(entity) || StringUtils.isBlank(entity.getId())) {
            return CommonResult.error().setErrorCode("id is not exist")
                    .setMessage("ID不存在");
        }
        // 删除数据
        repository.deleteFrpcManageInfoById(dto);
        // 解析远程frpc文件
        Map<String, FrpcIniObj> parseFrpcMap;
        try {
            parseFrpcMap = parseFrpcInI.parseFrpcIni();
        } catch (Exception e) {
            throw new YwuRuntimeException("deleteFrpcInfo parse Frpc Error !!!");
        }
        if (!parseFrpcMap.containsKey(entity.getFrpcName())) {
            log.warn("deleteFrpcInfo frpcName not exists");
            return CommonResult.success(null);
        }
        // 删除map中的数据
        parseFrpcMap.remove(entity.getFrpcName());
        // 重新写入frpc文件
        try {
            parseFrpcInI.reWriteFrpcIni(parseFrpcMap);
        } catch (IOException | IllegalAccessException e) {
            throw new YwuRuntimeException("deleteFrpcInfo reWriteFrpcIni Error !!!");
        }
        // 调用脚本执行停用和启用frpc
        parseFrpcInI.reloadFrpc();
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 分页查询
    * @Date 16:47 2024/7/13
    * @Param [manageDto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> queryPageList(FrpcManageDto manageDto) {
        // 查询分页的数量
        int count = repository.queryPageCount(manageDto);
        // 构建分页参数查询
        PageService.execPageStartAndEnd(manageDto.getPageInfo());
        List<FrpcManageEntity> resList = repository.queryPageList(manageDto);
        // 构建返参
        PageList<FrpcManageEntity> pageRes = new PageList<>(manageDto.getPageInfo().getPageIndex(),
                manageDto.getPageInfo().getPageSize(), count, resList);
        return CommonResult.success(pageRes);
    }

    /**
    * @Author GroundDemo
    * @Description 查询当前frpc所有运行的接口映射实例状态
    * @Date 20:29 2024/7/13
    * @Param []
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> queryFrpcInstanceStatus(FrpcManageDto manageDto) {
        // 通过ssh执行命令
        List<FrpcStatusEntity> frpcStatusEntities = parseFrpcInI.queryFrpcInstance();
        // 根据名称过滤数据
        List<FrpcStatusEntity> collect = frpcStatusEntities.stream().filter(res -> res.getName().contains(manageDto.getFrpcName()))
                .collect(Collectors.toList());
        return CommonResult.success(collect);
    }
}
